#define _FILE_OFFSET_BITS 64
#define	_LARGEFILE_SOURCE
#define __USE_LARGEFILE

#include "pfs.h"
#include "utils.h"
#include "lib_fuse.h"

//Nota: El proceso debe ser levantado con: ./PFS pathAlPuntoDeMontaje -f


//pthread_mutex_t mutexFAT = PTHREAD_MUTEX_INITIALIZER;

int main(int argc, char *argv[]) {

	system("clear");
	signal (SIGUSR1, trataSenial); /*crea el archivo cache_dump.txt*/

//	int				iRtaSelect;
	int				i = 0;
	pthread_t   	thrdFUSE;
	unsigned int 	value;

	// Inicializamos la cache
	stCache = NULL;

	if (argc < 2) {
		printf("Se debe especifar al menos el punto de montaje \n");
		return -1;
	}

	cargarConfiguracion(&stPFS);
	iniciarLog( "pfsLog.txt" );
	loguear( "pfsLog.txt", "PFS", "INFO", "Inicia el proceso PFS");
	value = (unsigned int ) stPFS.iMaxConexiones;

	printf("=====================================================================\n");
	printf("\t\t Proceso File System (PFS)\n IP: %s\n PUERTO: %i\n",stPFS.szIp,stPFS.iPuerto);
	printf("=====================================================================\n");

	if ( sem_init ( &semaforoConexiones, 0, value ) == -1) //0 indica que el semáforo sólo se puede utilizar por el proceso que lo crea (threads)
	{
		perror("ERROR: creacion de semaforo");
		printf("El semaforo no pudo ser inicializado\n");
	}

	if ( sem_init ( &semaforoTablaFAT, 0, 1 ) == -1) //0 indica que el semáforo sólo se puede utilizar por el proceso que lo crea (threads)
	{
		perror("ERROR: creacion de semaforo");
		printf("El semaforo no pudo ser inicializado\n");
	}

	//printf("paso los semaforos \n");

	if( stPFS.iTamCache != 0 ) {
		if ( sem_init ( &semaforoListaCache, 0, 1 ) == -1) //0 indica que el semáforo sólo se puede utilizar por el proceso que lo crea (threads)
		{
			perror("ERROR: creacion de semaforo");
			printf("El semaforo no pudo ser inicializado\n");
		}
	}

//	FD_ZERO( &maestroLecturaFD );
//	FD_ZERO( &descLecturaFD );
//	FD_ZERO( &maestroEscrituraFD );
//	FD_ZERO( &descEscrituraFD );

	if(stPFS.iPuertoRemoto != 0) { /*Se conectara a un ppd o raid*/
		if (conexionAlmacenamiento() < 0)
			return -1;

//		FD_SET( stPFS.iSocketRemoto, &maestroLecturaFD );
//		MAXDESC( iMaxDescriptor, stPFS.iSocketRemoto );

		// genera estructura con los args del main, para usarla desde el FUSE THREAD
		stARGS.argc = argc;
		for (i = 0; i < argc; i++) {
			stARGS.argv[i] = argv[i];
		}


//		sleep(2);	// para que salgan lindos los cartelitos...
		cargarBootSector();
		sem_wait(&semaforoTablaFAT);
		printf("\n Cargando Tabla FAT...\n");
		cargarFatTable();
		printf("\n Carga Completa. \n\n");
		sem_post( &semaforoTablaFAT );
		close(stPFS.iSocketRemoto);
		
		if (pthread_create(&thrdFUSE, NULL, (void *)inicializarFUSE, NULL) != 0) {
			perror("Error al crear FUSE THREAD");
			return -1;
		}
		//escribirLeer();

//		FD_SET( STDIN, &maestroLecturaFD );
//		MAXDESC( iMaxDescriptor, STDIN );	/*Establezco el nuevo descriptor maximo*/

		while ( 1 ) {

//			descLecturaFD = maestroLecturaFD;
//			iRtaSelect = select( iMaxDescriptor + 1, &descLecturaFD, NULL, NULL, NULL );
//
//			if( FD_ISSET( STDIN, &descLecturaFD ) ){ /*Se recibio un comando de consola*/
				if (procesaComando() == -2) {
					finPFS();
					break;
				}
//			}

		} /*fin del while(1)*/
	}

	printf("Fin del proceso\n\n");
	return 0;
}

void inicializarFUSE() {
	fuse_main(stARGS.argc, stARGS.argv, &pfs_oper, NULL);
 }


